import { getVSCodeDownloadUrl } from '@vscode/test-electron/out/util';
import * as fs from 'fs';
import * as path from 'path'
import * as vscode from 'vscode'
import * as def from './DistBuildDefintions'


export class DistBuildDataManager {
    private static distBuildDataManager: DistBuildDataManager
    private constructor(private rootDir: string) {
        this.getDistBuildState()
        this.getDistHosts()
    }
    private _distHosts: def.DistBuildHostDefinition[] | undefined;
    private _distBuildState: Map<string, def.DistBuildStateFile[]> = new Map();

    public static getInstance(rootDir: string) {
        if (!this.distBuildDataManager) {
            this.distBuildDataManager = new DistBuildDataManager(rootDir)
        }
        return this.distBuildDataManager
    }

    private checkDir(): string {
        let filedir: string = path.join(this.rootDir, def.CONFIG_DIR);
        if (!fs.existsSync(filedir)) {

            fs.mkdirSync(filedir, { recursive: true });
        } else {
            let stat = fs.lstatSync(filedir)
            if (!stat.isDirectory()) {
                fs.mkdirSync(filedir, { recursive: true });
            }
        }
        return filedir
    }
    private writeJson<T>(data: T, fileName: string): boolean {
        let filedir = this.checkDir();
        if (filedir === undefined) {
            return false;
        }
        let filePath = path.join(filedir, fileName);
        if (fs.existsSync(filePath)) {
            fs.rmSync(filePath);
        }

        fs.writeFileSync(filePath, JSON.stringify(data));
        return true;
    }

    private readJson<T>(fileName: string): T | undefined {
        //JSON.parse(fs.readFileSync(distHostsPath, "utf8"))
        let filedir = this.checkDir()
        if (filedir === undefined) {
            return undefined;
        }

        let filepath: string = path.join(filedir, fileName);
        if (!fs.existsSync(filepath)) {
            return undefined
        }
        let haha = fs.readFileSync(filepath, 'utf-8');
        let data: T = JSON.parse(fs.readFileSync(filepath, 'utf-8'));
        return data
    }
    public getDistHosts(): def.DistBuildHostDefinition[] {
        if (this._distHosts === undefined) {
            this._distHosts = this.readJson<def.DistBuildHostDefinition[]>('disthosts.json') ?? [];
        }
        return this._distHosts
    }

    public addDistHost(host: def.DistBuildHostDefinition): boolean {
        let exist: boolean = false;
        for (const val of this._distHosts ?? []) {
            if (val.address === host.address) {
                exist = true;
                break;
            }
        }
        this._distHosts?.push(host);
        //this.writeJson(this._distHosts, 'disthosts.json')
        return exist;
    }

    public stopDistHost(host: string): boolean {
        for (const val of this._distHosts ?? []) {
            if (val.address === host && val.state === def.DistBuildHostState.RUN) {
                val.state = def.DistBuildHostState.STOP
                break;
            }
        }
        return true
    }
    public removeDistHost(host: string) {
        this._distHosts = this._distHosts?.filter(obj => obj.address !== host);
        //this._distBuildState = this._distBuildState?.filter(obj => obj.address != host);
    }
    public runDistHost(host: string): boolean {
        for (const val of this._distHosts ?? []) {
            if (val.address === host && val.state === def.DistBuildHostState.STOP) {
                val.state = def.DistBuildHostState.RUN
                break;
            }
        }
        return true
    }

    public cleanDistBuildState() {
        this._distBuildState.clear()
        vscode.commands.executeCommand('distbuild.refresh')
    }
    public updateDistBuildState(address: string, files: def.DistBuildStateFile[]) {
        this._distBuildState.set(address, files)
        vscode.commands.executeCommand('distbuild.refresh')
    }
    public getRunningNum(address: string): number {
        if (this._distBuildState.has(address)) {
            return this._distBuildState.get(address)?.length ?? 0
        }
        return 0
    }
    public getDistBuildState(): Map<string, def.DistBuildStateFile[]> {
        return this._distBuildState
    }

    public storage() {
        this.writeJson(this._distHosts, 'disthosts.json')
        //this.writeJson(this._distBuildState, 'distbuildstate.json')
    }

}